// Ninf-G-XX, ver. 0.1
// Copyright 2011 National Institute of Advanced Industrial Science and Technology
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
 * ByteArrayOutputStream.cpp
 *
 *  Created on: Jan 29, 2009
 *      Author: nakada
 */
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include "GrpcException.hpp"
#include "ByteArrayOutputStream.hpp"

namespace ninf {

namespace lib {

ByteArrayOutputStream::ByteArrayOutputStream(size_t initial_size, size_t grow_size, bool freeOnDelete):
  freeOnDelete(freeOnDelete){
  array = NULL;
  grow(initial_size);
  this->offset = 0;
  this->grow_size = grow_size;
}

ByteArrayOutputStream::~ByteArrayOutputStream() {
  if (array != NULL && freeOnDelete)
    free(array);
}

/**
 *  write out a single byte
 *  */
void ByteArrayOutputStream::write(int c){
  while (current_size < this->offset + 1)
    grow(current_size + grow_size);
  *(array + this->offset++) = (unsigned char)c;
}

/**
 *  write out array of bytes
 *  */
void ByteArrayOutputStream::write(const char * val, int offset, int len) {
  if (current_size < this->offset + len)
    grow(current_size + len + grow_size);
  memcpy(array + this->offset, val+offset, len);
  this->offset += len;
}

bool ByteArrayOutputStream::grow(size_t size){
  array = (char*)realloc(array, size);
  if (array == NULL)
    throw GRPC_EXCEPTION("cannot allocate memory for byte array", GRPC_OTHER_ERROR_CODE);
  this->current_size = size;
  return true;
}

void ByteArrayOutputStream::dump(){
  printf("len=%d: ", (int)length());
  char * buf = getBytes();
  for (int i = 0; i < (int)length(); i++)
    printf("%02x ", 0xff & *(buf+i));
  printf("\n");
}
}
}
